﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Threading;

namespace CS633_Final_Project
{
    public partial class Form1 : Form
    {
        private Environment environment;
        private const float LEFT_MARGIN = 25;
        private const float TOP_MARGIN = 50;

        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (environment != null)
                drawEnvironment(e);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void runMethod1ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {

        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "Polygon File (*.poly)|*.poly";
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.ShowDialog();

            if (File.Exists(openFileDialog1.FileName))
                openEnvironment();
            else
                MessageBox.Show("Can't open file.");
        }

        private void closeEnvironmentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            environment = null;
            hScrollBar1.Enabled = false;
            Invalidate();
        }

        private void openEnvironment()
        {
            environment = new Environment(openFileDialog1.FileName, LEFT_MARGIN, TOP_MARGIN);
            environment.InitializeRobots(hScrollBar1.Value);
            hScrollBar1.Enabled = true;
            Invalidate();
        }

        private void drawEnvironment(PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            Pen pen = new Pen(Color.Black, 8);
            SolidBrush brush = new SolidBrush(Color.White);
            PointF[] points = environment.GetPoints();

            graphics.DrawPolygon(pen, points);
            graphics.FillPolygon(brush, points);
            drawTriangulation(graphics);
            drawRobots(graphics);

            graphics.Dispose();
        }

        private void drawTriangulation(Graphics graphics)
        {
            Pen pen = new Pen(Color.Blue, 1);
            foreach (Triangle triangle in environment.Triangles)
                graphics.DrawPolygon(pen, triangle.Vertices);
        }

        private void drawRobots(Graphics graphics)
        {
            Font font = new Font("Helvetica", 14);
            Brush brush = new SolidBrush(Color.Red);

            // draw the evader
            graphics.DrawString("E", font, brush, environment.Evader.Location);

            brush = new SolidBrush(Color.Green);
            foreach (Robot pursuer in environment.Pursuers)
                graphics.DrawString("P", font, brush, pursuer.Location);
        }

        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            pursuerNumLabel.Text = hScrollBar1.Value.ToString();
            environment.InitializeRobots(hScrollBar1.Value);
            Invalidate();
        }

        private void runMethod2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openEnvironment();
        }

        private void greedyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            hScrollBar1.Enabled = false;
            label2.Text = "Searching...";

            // run the greedy algorithm
            greedyPlannerWorker.DoWork += greedyPlannerThread_DoWork;
            greedyPlannerWorker.RunWorkerCompleted += greedyPlannerThread_RunWorkerCompleted;
            greedyPlannerWorker.WorkerSupportsCancellation = true;
            greedyPlannerWorker.RunWorkerAsync();

            // run the evader movement thread.
            evaderUpdateWorker.DoWork += evaderUpdateWorker_DoWork;
            evaderUpdateWorker.RunWorkerAsync();

            // run the gui update thread
            guiUpdateWorker.DoWork += guiUpdateWorker_DoWork;
            guiUpdateWorker.RunWorkerAsync();
        }

        private void greedyPlannerThread_DoWork(object sender, DoWorkEventArgs e)
        {
            GreedyAreaPlanner mp = new GreedyAreaPlanner(environment);
            mp.Move();
        }

        private void greedyPlannerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            hScrollBar1.Enabled = true;
            label2.Text = "Caught!";
        }

        private void guiUpdateWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (!hScrollBar1.Enabled)
            {
                Invalidate();
                Thread.Sleep(200);
            }

        }

        private void evaderUpdateWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            EvaderPlanner mp = new EvaderPlanner(environment);
            mp.Move();
        }

        private void standardToolStripMenuItem_Click(object sender, EventArgs e)
        {
            hScrollBar1.Enabled = false;
            label2.Text = "Searching...";

            // run the greedy algorithm
            triangulatedVisibilityWorker.DoWork += triangulatedVisibilityWorker_DoWork;
            triangulatedVisibilityWorker.RunWorkerCompleted += triangulatedVisibilityWorker_RunWorkerCompleted;
            triangulatedVisibilityWorker.RunWorkerAsync();

            // run the evader movement thread.
            evaderUpdateWorker.DoWork += evaderUpdateWorker_DoWork;
            evaderUpdateWorker.RunWorkerAsync();

            // run the gui update thread
            guiUpdateWorker.DoWork += guiUpdateWorker_DoWork;
            guiUpdateWorker.RunWorkerAsync();
        }

        private void triangulatedVisibilityWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            TriangulatedVisibilityPlanner mp = new TriangulatedVisibilityPlanner(environment);
            mp.Move();
        }

        private void triangulatedVisibilityWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            hScrollBar1.Enabled = true;
            label2.Text = "Caught!";
        }
    }
}
